/**
 * 键盘事件工具函数 - JavaScript版本
 * 提供键盘事件监听、按键禁用、组合键处理等功能
 * 支持直接复制粘贴使用，无需任何依赖
 * 每个函数都是独立的，可以单独复制使用
 */

// 常量定义
const KEYBOARD_EVENT_TYPES = {
  KEYDOWN: 'keydown',
  KEYUP: 'keyup',
  KEYPRESS: 'keypress'
};

const PLATFORMS = {
  MAC: 'mac',
  WINDOWS: 'windows',
  LINUX: 'linux',
  UNKNOWN: 'unknown'
};

// 全局监听器存储
let listeners = new Map();
let disabledKeys = new Set();
let navigationConfig = null;

/**
 * 检测平台
 * @returns {string} 平台类型
 */
function detectPlatform() {
  const userAgent = navigator.userAgent.toLowerCase();
  const platform = navigator.platform.toLowerCase();
  
  if (userAgent.includes('mac') || platform.includes('mac')) {
    return PLATFORMS.MAC;
  } else if (userAgent.includes('win') || platform.includes('win')) {
    return PLATFORMS.WINDOWS;
  } else if (userAgent.includes('linux') || platform.includes('linux')) {
    return PLATFORMS.LINUX;
  }
  
  return PLATFORMS.UNKNOWN;
}

/**
 * 获取当前平台
 * @returns {string} 平台类型
 */
function getPlatform() {
  return detectPlatform();
}

/**
 * 检查是否为Mac系统
 * @returns {boolean} 是否为Mac系统
 */
function isMacOS() {
  return getPlatform() === PLATFORMS.MAC;
}

/**
 * 获取平台修饰键
 * @param {string} key - 基础键
 * @returns {string} 平台修饰键
 */
function getPlatformModifier(key) {
  const platform = getPlatform();
  
  if (platform === PLATFORMS.MAC) {
    return key.replace('ctrl', 'cmd');
  }
  
  return key;
}

/**
 * 获取平台快捷键显示文本
 * @param {string} shortcut - 快捷键
 * @returns {string} 显示文本
 */
function getPlatformShortcutText(shortcut) {
  const platform = getPlatform();
  
  if (platform === PLATFORMS.MAC) {
    return shortcut
      .replace(/ctrl/gi, '⌘')
      .replace(/alt/gi, '⌥')
      .replace(/shift/gi, '⇧')
      .replace(/meta/gi, '⌘');
  }
  
  return shortcut;
}

/**
 * 添加键盘监听器
 * @param {string} id - 监听器ID
 * @param {string} eventType - 事件类型
 * @param {Object} config - 事件配置
 * @param {Function} handler - 处理函数
 * @param {HTMLElement} [element] - 目标元素
 * @returns {Function} 移除监听器的函数
 */
function addListener(id, eventType, config = {}, handler, element = document) {
  // 检查是否已存在相同ID的监听器
  if (listeners.has(id)) {
    console.warn(`监听器 ${id} 已存在，将被替换`);
    removeListener(id);
  }
  
  const listener = {
    id,
    eventType,
    config,
    handler,
    element,
    active: true
  };
  
  const eventHandler = (event) => {
    if (!listener.active) return;
    
    // 检查按键是否被禁用
    if (disabledKeys.has(event.key) || disabledKeys.has(event.code)) {
      event.preventDefault();
      return;
    }
    
    // 检查事件配置
    if (config.key && event.key !== config.key) return;
    if (config.code && event.code !== config.code) return;
    if (config.ctrlKey !== undefined && event.ctrlKey !== config.ctrlKey) return;
    if (config.shiftKey !== undefined && event.shiftKey !== config.shiftKey) return;
    if (config.altKey !== undefined && event.altKey !== config.altKey) return;
    if (config.metaKey !== undefined && event.metaKey !== config.metaKey) return;
    
    // 执行处理函数
    if (config.preventDefault) {
      event.preventDefault();
    }
    if (config.stopPropagation) {
      event.stopPropagation();
    }
    
    handler(event);
    
    // 如果是一次性监听器，移除它
    if (config.once) {
      removeListener(id);
    }
  };
  
  element.addEventListener(eventType, eventHandler);
  listener.eventHandler = eventHandler;
  
  listeners.set(id, listener);
  
  // 返回移除监听器的函数
  return () => removeListener(id);
}

/**
 * 移除键盘监听器
 * @param {string} id - 监听器ID
 */
function removeListener(id) {
  const listener = listeners.get(id);
  if (listener) {
    listener.element.removeEventListener(listener.eventType, listener.eventHandler);
    listeners.delete(id);
  }
}

/**
 * 移除所有监听器
 */
function removeAllListeners() {
  listeners.forEach((listener) => {
    listener.element.removeEventListener(listener.eventType, listener.eventHandler);
  });
  listeners.clear();
}

/**
 * 添加回车键监听器
 * @param {string} id - 监听器ID
 * @param {Function} handler - 处理函数
 * @param {HTMLElement} [element] - 目标元素
 * @returns {Function} 移除监听器的函数
 */
function addEnterListener(id, handler, element = document) {
  return addListener(id, KEYBOARD_EVENT_TYPES.KEYDOWN, {
    key: 'Enter',
    preventDefault: true
  }, handler, element);
}

/**
 * 添加ESC键监听器
 * @param {string} id - 监听器ID
 * @param {Function} handler - 处理函数
 * @param {HTMLElement} [element] - 目标元素
 * @returns {Function} 移除监听器的函数
 */
function addEscapeListener(id, handler, element = document) {
  return addListener(id, KEYBOARD_EVENT_TYPES.KEYDOWN, {
    key: 'Escape',
    preventDefault: true
  }, handler, element);
}

/**
 * 添加Tab键监听器
 * @param {string} id - 监听器ID
 * @param {Function} handler - 处理函数
 * @param {HTMLElement} [element] - 目标元素
 * @returns {Function} 移除监听器的函数
 */
function addTabListener(id, handler, element = document) {
  return addListener(id, KEYBOARD_EVENT_TYPES.KEYDOWN, {
    key: 'Tab',
    preventDefault: true
  }, handler, element);
}

/**
 * 添加空格键监听器
 * @param {string} id - 监听器ID
 * @param {Function} handler - 处理函数
 * @param {HTMLElement} [element] - 目标元素
 * @returns {Function} 移除监听器的函数
 */
function addSpaceListener(id, handler, element = document) {
  return addListener(id, KEYBOARD_EVENT_TYPES.KEYDOWN, {
    key: ' ',
    preventDefault: true
  }, handler, element);
}

/**
 * 添加快捷键监听器
 * @param {string} id - 监听器ID
 * @param {string} shortcut - 快捷键字符串
 * @param {Function} handler - 处理函数
 * @param {HTMLElement} [element] - 目标元素
 * @returns {Function} 移除监听器的函数
 */
function addShortcut(id, shortcut, handler, element = document) {
  const keys = shortcut.toLowerCase().split('+').map(key => key.trim());
  
  let config = {};
  
  // 解析修饰键
  if (keys.includes('ctrl')) config.ctrlKey = true;
  if (keys.includes('shift')) config.shiftKey = true;
  if (keys.includes('alt')) config.altKey = true;
  if (keys.includes('meta') || keys.includes('cmd')) config.metaKey = true;
  
  // 获取主键
  const mainKey = keys[keys.length - 1];
  config.key = mainKey;
  config.preventDefault = true;
  
  return addListener(id, KEYBOARD_EVENT_TYPES.KEYDOWN, config, handler, element);
}

/**
 * 添加Mac兼容的快捷键监听器
 * @param {string} id - 监听器ID
 * @param {string} shortcut - 快捷键字符串
 * @param {Function} handler - 处理函数
 * @param {HTMLElement} [element] - 目标元素
 * @returns {Function} 移除监听器的函数
 */
function addMacCompatibleShortcut(id, shortcut, handler, element = document) {
  const platform = getPlatform();
  let actualShortcut = shortcut;
  
  if (platform === PLATFORMS.MAC) {
    actualShortcut = shortcut.replace(/ctrl/gi, 'cmd');
  }
  
  return addShortcut(id, actualShortcut, handler, element);
}

/**
 * 添加跨平台快捷键监听器
 * @param {string} id - 监听器ID
 * @param {Object} shortcuts - 平台快捷键配置
 * @param {Function} handler - 处理函数
 * @param {HTMLElement} [element] - 目标元素
 * @returns {Function} 移除监听器的函数
 */
function addCrossPlatformShortcut(id, shortcuts, handler, element = document) {
  const platform = getPlatform();
  const shortcut = shortcuts[platform] || shortcuts.default || shortcuts;
  
  return addShortcut(id, shortcut, handler, element);
}

/**
 * 禁用特定按键
 * @param {string} key - 要禁用的按键
 */
function disableKey(key) {
  disabledKeys.add(key);
}

/**
 * 启用特定按键
 * @param {string} key - 要启用的按键
 */
function enableKey(key) {
  disabledKeys.delete(key);
}

/**
 * 禁用所有常用按键
 */
function disableAllKeys() {
  const commonKeys = [
    'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12',
    'Tab', 'CapsLock', 'Shift', 'Control', 'Alt', 'Meta',
    'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight',
    'PageUp', 'PageDown', 'Home', 'End', 'Insert', 'Delete',
    'Backspace', 'Enter', 'Escape'
  ];
  
  commonKeys.forEach(key => disabledKeys.add(key));
}

/**
 * 启用所有按键
 */
function enableAllKeys() {
  disabledKeys.clear();
}

/**
 * 检查是否按下了组合键
 * @param {KeyboardEvent} event - 键盘事件
 * @param {Array} keys - 按键数组
 * @returns {boolean} 是否按下了组合键
 */
function isComboPressed(event, keys) {
  const pressedKeys = [];
  
  if (event.ctrlKey) pressedKeys.push('ctrl');
  if (event.shiftKey) pressedKeys.push('shift');
  if (event.altKey) pressedKeys.push('alt');
  if (event.metaKey) pressedKeys.push('meta');
  pressedKeys.push(event.key.toLowerCase());
  
  return keys.every(key => pressedKeys.includes(key.toLowerCase()));
}

/**
 * 获取当前按下的修饰键
 * @param {KeyboardEvent} event - 键盘事件
 * @returns {Array} 修饰键数组
 */
function getPressedModifiers(event) {
  const modifiers = [];
  
  if (event.ctrlKey) modifiers.push('ctrl');
  if (event.shiftKey) modifiers.push('shift');
  if (event.altKey) modifiers.push('alt');
  if (event.metaKey) modifiers.push('meta');
  
  return modifiers;
}

/**
 * 设置键盘导航
 * @param {Object} config - 导航配置
 */
function setupNavigation(config) {
  navigationConfig = {
    selector: config.selector || '.nav-item',
    loop: config.loop !== false,
    orientation: config.orientation || 'vertical',
    ...config
  };
  
  // 添加键盘导航监听器
  addListener('keyboard-navigation', KEYBOARD_EVENT_TYPES.KEYDOWN, {
    key: 'Tab',
    preventDefault: true
  }, handleNavigation);
  
  addListener('keyboard-navigation-arrows', KEYBOARD_EVENT_TYPES.KEYDOWN, {
    key: navigationConfig.orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight',
    preventDefault: true
  }, handleNavigation);
  
  addListener('keyboard-navigation-arrows-reverse', KEYBOARD_EVENT_TYPES.KEYDOWN, {
    key: navigationConfig.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft',
    preventDefault: true
  }, handleNavigation);
}

/**
 * 处理键盘导航
 * @param {KeyboardEvent} event - 键盘事件
 */
function handleNavigation(event) {
  if (!navigationConfig) return;
  
  const elements = document.querySelectorAll(navigationConfig.selector);
  const currentElement = document.activeElement;
  const currentIndex = Array.from(elements).indexOf(currentElement);
  
  let nextIndex = currentIndex;
  
  if (event.key === 'Tab') {
    nextIndex = event.shiftKey ? currentIndex - 1 : currentIndex + 1;
  } else if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {
    nextIndex = currentIndex + 1;
  } else if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
    nextIndex = currentIndex - 1;
  }
  
  // 处理循环导航
  if (navigationConfig.loop) {
    if (nextIndex < 0) nextIndex = elements.length - 1;
    if (nextIndex >= elements.length) nextIndex = 0;
  } else {
    if (nextIndex < 0) nextIndex = 0;
    if (nextIndex >= elements.length) nextIndex = elements.length - 1;
  }
  
  if (nextIndex !== currentIndex && elements[nextIndex]) {
    elements[nextIndex].focus();
  }
}

/**
 * 清理所有键盘事件
 */
function cleanup() {
  removeAllListeners();
  enableAllKeys();
  navigationConfig = null;
}

/**
 * 获取所有监听器
 * @returns {Array} 监听器数组
 */
function getAllListeners() {
  return Array.from(listeners.values());
}

/**
 * 获取监听器数量
 * @returns {number} 监听器数量
 */
function getListenerCount() {
  return listeners.size;
}

/**
 * 检查监听器是否存在
 * @param {string} id - 监听器ID
 * @returns {boolean} 是否存在
 */
function hasListener(id) {
  return listeners.has(id);
}

/**
 * 暂停监听器
 * @param {string} id - 监听器ID
 */
function pauseListener(id) {
  const listener = listeners.get(id);
  if (listener) {
    listener.active = false;
  }
}

/**
 * 恢复监听器
 * @param {string} id - 监听器ID
 */
function resumeListener(id) {
  const listener = listeners.get(id);
  if (listener) {
    listener.active = true;
  }
}

/**
 * 暂停所有监听器
 */
function pauseAllListeners() {
  listeners.forEach(listener => {
    listener.active = false;
  });
}

/**
 * 恢复所有监听器
 */
function resumeAllListeners() {
  listeners.forEach(listener => {
    listener.active = true;
  });
}

// 支持多种导出方式
if (typeof module !== 'undefined' && module.exports) {
  // Node.js 环境
  module.exports = {
    // 函数式导出
    addListener,
    removeListener,
    removeAllListeners,
    addEnterListener,
    addEscapeListener,
    addTabListener,
    addSpaceListener,
    addShortcut,
    addMacCompatibleShortcut,
    addCrossPlatformShortcut,
    disableKey,
    enableKey,
    disableAllKeys,
    enableAllKeys,
    isComboPressed,
    getPressedModifiers,
    setupNavigation,
    cleanup,
    getAllListeners,
    getListenerCount,
    hasListener,
    pauseListener,
    resumeListener,
    pauseAllListeners,
    resumeAllListeners,
    detectPlatform,
    getPlatform,
    isMacOS,
    getPlatformModifier,
    getPlatformShortcutText,
    // 常量导出
    KEYBOARD_EVENT_TYPES,
    PLATFORMS
  };
} else if (typeof window !== 'undefined') {
  // 浏览器环境
  window.addListener = addListener;
  window.removeListener = removeListener;
  window.removeAllListeners = removeAllListeners;
  window.addEnterListener = addEnterListener;
  window.addEscapeListener = addEscapeListener;
  window.addTabListener = addTabListener;
  window.addSpaceListener = addSpaceListener;
  window.addShortcut = addShortcut;
  window.addMacCompatibleShortcut = addMacCompatibleShortcut;
  window.addCrossPlatformShortcut = addCrossPlatformShortcut;
  window.disableKey = disableKey;
  window.enableKey = enableKey;
  window.disableAllKeys = disableAllKeys;
  window.enableAllKeys = enableAllKeys;
  window.isComboPressed = isComboPressed;
  window.getPressedModifiers = getPressedModifiers;
  window.setupNavigation = setupNavigation;
  window.cleanup = cleanup;
  window.getAllListeners = getAllListeners;
  window.getListenerCount = getListenerCount;
  window.hasListener = hasListener;
  window.pauseListener = pauseListener;
  window.resumeListener = resumeListener;
  window.pauseAllListeners = pauseAllListeners;
  window.resumeAllListeners = resumeAllListeners;
  window.detectPlatform = detectPlatform;
  window.getPlatform = getPlatform;
  window.isMacOS = isMacOS;
  window.getPlatformModifier = getPlatformModifier;
  window.getPlatformShortcutText = getPlatformShortcutText;
  window.KEYBOARD_EVENT_TYPES = KEYBOARD_EVENT_TYPES;
  window.PLATFORMS = PLATFORMS;
}